package bll

import (
	"fmt"
	"time"

	"7qule.com/sd3/CrossServer/src/bll/player/dal"
	. "7qule.com/sd3/CrossServer/src/bll/player/model"
	"7qule.com/sd3/CrossServer/src/bll/world"
	"7qule.com/sd3/CrossServer/src/common/onlinelog"
	"7qule.com/sd3/CrossServer/src/common/systemConstant"
	"public.com/goutil/syncUtil"
)

// 公会信息务逻辑类
type globalGuildBll struct {
	// 公会信息数据
	data map[string]*GlobalGuild

	// 数据同步对象
	dataLock *syncUtil.RWLocker
}

// --------------------------------初始化--------------------------------------------------

// 公会信息逻辑类
var GlobalGuildBll = &globalGuildBll{
	dataLock: syncUtil.NewRWLocker(),
}

// 初始化
func init() {
	// 注册数据初始化函数
	world.LoadMgr.RegisterFunc(GlobalGuildBll.StructName(), GlobalGuildBll.initData)
}

// StructName 模块名
func (this *globalGuildBll) StructName() string {
	return "GlobalGuildBll"
}

// initData 初始化数据
// 返回值:
// err:错误信息
func (this *globalGuildBll) initData() (errList []error) {
	tempList, err := dal.GlobalGuildDal.GetData()
	if err != nil {
		errList = append(errList, err)
		return
	}

	tempMap := make(map[string]*GlobalGuild)
	for _, item := range tempList {
		tempMap[item.GuildId] = item
	}

	if isOk, prevStack, currStack := this.dataLock.Lock(systemConstant.DefaultLockTime); isOk == false {
		errMsg := fmt.Sprintf("Lock timeout! \n上一个堆栈:\n%s  \n当前堆栈:\n%s", prevStack, currStack)
		onlinelog.ErrorLog(errMsg)
		panic(errMsg)
	}
	defer this.dataLock.Unlock()

	this.data = tempMap

	return
}

// --------------------------------生成的基础方法--------------------------------------------------

// GetData 获取数据
// 返回值:
// []*GlobalGuild:获取到的公会信息数据
func (this *globalGuildBll) GetData() map[string]*GlobalGuild {
	if isOk, prevStack, currStack := this.dataLock.RLock(systemConstant.DefaultLockTime); isOk == false {
		errMsg := fmt.Sprintf("Lock timeout! \n上一个堆栈:\n%s  \n当前堆栈:\n%s", prevStack, currStack)
		onlinelog.ErrorLog(errMsg)
		panic(errMsg)
	}
	defer this.dataLock.RUnlock()

	return this.data
}

// 获取或初始化数据
// 返回值:
// 		*GlobalGuild:获取到的公会信息数据
//		是否是新数据
func (this *globalGuildBll) GetOrInitItem(guildId string) (*GlobalGuild, bool) {
	//获取数据-读锁
	item, exists := this.GetItem(guildId)
	if exists {
		return item, false
	}

	//初始化数据 - 写锁
	item, exists = this.initItem(guildId)
	if exists {
		return item, false
	}

	return item, true
}

// GetItem 获取数据
// 返回值:
// *GlobalGuild:获取到的公会信息数据
func (this *globalGuildBll) GetItem(guildId string) (result *GlobalGuild, exists bool) {
	if isOk, prevStack, currStack := this.dataLock.RLock(systemConstant.DefaultLockTime); isOk == false {
		errMsg := fmt.Sprintf("Lock timeout! \n上一个堆栈:\n%s  \n当前堆栈:\n%s", prevStack, currStack)
		onlinelog.ErrorLog(errMsg)
		panic(errMsg)
	}
	defer this.dataLock.RUnlock()

	result, exists = this.data[guildId]

	return
}

// 初始化数据
// 返回值:
// 		*GlobalGuild:获取到的公会信息数据
//		是否存在
func (this *globalGuildBll) initItem(guildId string) (*GlobalGuild, bool) {
	if isOk, prevStack, currStack := this.dataLock.Lock(systemConstant.DefaultLockTime); isOk == false {
		errMsg := fmt.Sprintf("Lock timeout! \n上一个堆栈:\n%s  \n当前堆栈:\n%s", prevStack, currStack)
		onlinelog.ErrorLog(errMsg)
		panic(errMsg)
	}
	defer this.dataLock.Unlock()

	result, exists := this.data[guildId]
	if exists {
		return result, true
	}

	result = NewGlobalGuild(guildId, "", 0, "", "", "", 0, 0,
		"", time.Now())

	this.data[guildId] = result

	return result, false
}

// --------------------------------内部方法--------------------------------------------------

// insert 数据插入
// data:公会数据
func (this *globalGuildBll) insert(data *GlobalGuild) {
	dal.GlobalGuildDal.Insert(data)
}

// update 更新数据
// data:公会数据对象
func (this *globalGuildBll) update(data *GlobalGuild) {
	dal.GlobalGuildDal.Update(data)
}

// delete 删除数据
// data:公会数据对象
func (this *globalGuildBll) delete(id string) {
	dal.GlobalGuildDal.Delete(id)
}

// --------------------------------外部方法--------------------------------------------------

// UpdateInfo 更新数据
func (this *globalGuildBll) UpdateInfo(guildId, guildName string, lv int32, flag, logo, bannerInfo string,
	serverGroupId, serverId int32, serverName string) {
	//获取或初始化数据
	data, isNewItem := this.GetOrInitItem(guildId)

	//更新数据
	data.GuildName = guildName
	data.Lv = lv
	data.Flag = flag
	data.Logo = logo
	data.ServerGroupId = serverGroupId
	data.ServerId = serverId
	data.ServerName = serverName
	data.BannerInfo = bannerInfo
	data.UpdateTime = time.Now()

	//如果是新数据则插入，否则更新
	if isNewItem {
		dal.GlobalGuildDal.Insert(data)
	} else {
		dal.GlobalGuildDal.Update(data)
	}
}

// --------------------------------组织客户端数据--------------------------------------------------

// 获取组织数据
func (g *globalGuildBll) AssembleToClient(globalGuild *GlobalGuild) map[string]interface{} {
	// 对返回结果先赋初值
	resultMap := make(map[string]interface{}, 9)
	resultMap["GuildId"] = globalGuild.GuildId
	resultMap["GuildName"] = globalGuild.GuildName
	resultMap["Lv"] = globalGuild.Lv
	resultMap["Flag"] = globalGuild.Flag
	resultMap["Logo"] = globalGuild.Logo
	resultMap["BannerInfo"] = globalGuild.BannerInfo
	resultMap["ServerGroupId"] = globalGuild.ServerGroupId
	resultMap["ServerId"] = globalGuild.ServerId
	resultMap["ServerName"] = globalGuild.ServerName

	return resultMap
}
